package ssau.knyazev.core;

public class Complex {

	private float img;
	private float real;
	
	public Complex(float real, float img) {
		this.img = img;
		this.real = real;
	}
	
	public Complex() {
		new Complex(0, 0);
	}
	
	public float getImg() {
		return img;
	}
	
	public void setImg(float img) {
		this.img = img;
	}
	
	public float getReal() {
		return real;
	}
	
	public void setReal(float real) {
		this.real = real;
	}

	public Complex add(Complex x){
		float i = this.img + x.getImg();
		float r = this.real + x.getReal();
		return new Complex(r, i);		
	}
	
	public Complex sub(Complex x){
		float i = this.img - x.getImg();
		float r = this.real - x.getReal();
		return new Complex(r, i);
	}
	
	public Complex multy(Complex x){
		float i = this.img*x.getReal() + this.real*x.getImg();
		float r = this.real*x.getReal() - this.img*x.getImg();
		return new Complex(r, i);
	}
	
	public Complex devide(Complex x){
		double d = x.real*x.real + x.img*x.img;
		float re = (float) ((real*x.real + img*x.img)/d);
		float im = (float) ((-real*x.img + img*x.real)/d);
		return new Complex(re, im);
	}
	
	public Complex incBy(double x){
		return new Complex((float)(real+x), img);
	}
	
	public Complex decBy(double x){
		return new Complex((float)(real-x), img);
	}
	
	public Complex multyBy(double x){
		return new Complex((float)(real*x), (float)(img*x));
	}
	
	public Complex devideBy(double x){
		return new Complex((float)(real/x), (float)(img/x));
	}
	
	public double norm(Complex x){
		double norm;
		norm = x.getReal()*this.real - x.getImg()*this.img;
		return norm;
	}
	
	public static Complex exp(double power){
		Complex result = new Complex();
		result.setReal((float)Math.cos(power));
		result.setImg((float)Math.sin(power));
		return result;
	}
	
	/**
	 * W[n]^k
	 * 
	 * @param n
	 * @param k
	 * @return
	 */
	public static Complex W(int n, int k){
		double power = -2*Math.PI*k/n;
		return exp(power);
	}
	
	public Complex linked(){
		this.img = 0 - this.img;
		return this;		
	}
	
	@Override
	public String toString(){
		StringBuilder sb = new StringBuilder();
		sb.append(String.format("%.2f", real));
		double i = img;
		if ((i < 0 && i + 0.01 > 0) || (i > 0 && i - 0.01 < 0))
			i = 0;
		if (i != 0){
			if (i < 0)
				sb.append(" - ");
			else
				sb.append(" + ");
			sb.append(String.format("%.2fi", Math.abs(i)));
		}
		return sb.toString();
	}
	
	@Override
	public Complex clone(){
		return new Complex(real, img);
	}
	
	public void setZero(){
		this.real = 0;
		this.img = 0;
	}
	
	public float abs(){
		return (float)Math.sqrt(img*img + real*real);
	}
	

	
}
